Attribute VB_Name = "ListenerFunctions"
Option Explicit
 
Public Enum RegistrationListenerMethods
    rlmAfterAddded = 1
    rlmBeforeAdded = 2
    rlmAfterRemoved = 3
    rlmBeforeRemoved = 4
End Enum

Public Enum OperationsListenerMethods
    olmBeforeDisplayErrorsCancel = 1
    olmBeforePushErrorStack = 2
    olmprocessingError = 3
    olmAfterDisplayEndProgram = 4
    olmAfterDisplayContinueProgram = 5
End Enum

Public Enum ErrorListenerMethods
    elmErrorAdded = 1
    elmErrorCleared = 2
End Enum


Public Enum RegistrationListenerTypes
    rltOther = 1
    rltClass = 2
    rltMethod = 3
End Enum

Public Function getRegListenerTypeFromObject(ByVal pr_Object As Object) As RegistrationListenerTypes
Dim vl_RegType As RegistrationListenerTypes

If TypeOf pr_Object Is ErrorClass Then
    vl_RegType = rltClass
End If
If TypeOf pr_Object Is ErrorMethod Then
    vl_RegType = rltMethod
End If

getRegListenerTypeFromObject = vl_RegType
End Function




Private Sub invokeGenericListenerMethod( _
        ByVal listenerStack As ListenerQueue, _
        ByVal listenerMethod As String, _
        ParamArray argList() As Variant)
        
Dim vl_CurrentStackItem As Variant
Dim vl_StackIterator As LLIterator

Set vl_StackIterator = listenerStack.getIterator


Do While vl_StackIterator.hasCurrent
    Set vl_CurrentStackItem = vl_StackIterator.currentItem
    checkAndHandleNonInitializedObjectCustomErrorNumberAndDesc vl_CurrentStackItem, CP_ERROR_NONOBJECTINLISTENERSTACK, CP_ERROR_NONOBJECTINLISTENERSTACK_DESC
    
    'We use zero here becuase the original parameters were wrapped in an array. Since they were already
    'an array, zero returns the original arrray.
    callListeners vl_CurrentStackItem, listenerMethod, argList(0)
    vl_StackIterator.moveNext
Loop
End Sub

Public Sub invokeOperationsListeners( _
    ByVal listeners As ListenerQueue, _
    method As OperationsListenerMethods, _
    ParamArray argList() As Variant)

invokeGenericListenerMethod listeners, getOpsInterfaceMethodName(method), argList()
End Sub

Public Sub invokeErrorListeners( _
    ByVal listeners As ListenerQueue, _
    method As ErrorListenerMethods, _
    ParamArray argList() As Variant)
    
invokeGenericListenerMethod listeners, getErrorInterfaceMethodName(method), argList()
End Sub

Public Sub invokeRegistrationListeners( _
        ByVal listeners As ListenerQueue, _
        typeOfRegListener As RegistrationListenerTypes, _
        method As RegistrationListenerMethods, _
        ParamArray args() As Variant)
        
        
'NOTE: It is a VB6 IDE issue to occaisionally get stuck here during run. Try closing and reopening the group if a object not set error is encountered
invokeGenericListenerMethod listeners, getRegInterfaceMethodName(typeOfRegListener, method), args()
End Sub

Public Function getErrorInterfaceMethodName(pr_Method As ErrorListenerMethods)
Dim vl_MethodName As String

Select Case pr_Method
Case elmErrorAdded
    vl_MethodName = "ErrorAdded"
Case elmErrorCleared
    vl_MethodName = "ErrorCleared"
End Select

getErrorInterfaceMethodName = vl_MethodName
End Function

Public Function getOpsInterfaceMethodName(ByVal pr_Method As OperationsListenerMethods) As String
Dim vl_MethodName As String

Select Case pr_Method
    Case olmBeforeDisplayErrorsCancel
        vl_MethodName = "beforeDisplayErrorCancelOpprotunity"
    Case olmBeforePushErrorStack
        vl_MethodName = "beforePushErrorStackCancelOpprotunity"
    Case olmAfterDisplayEndProgram
        vl_MethodName = "afterDisplayErrorEndProgram"
    Case olmAfterDisplayContinueProgram
        vl_MethodName = "afterDisplayErrorContinueProgram"
End Select

getOpsInterfaceMethodName = vl_MethodName
End Function

Private Function getRegInterfaceMethodName(ByVal pr_InterfaceType As RegistrationListenerTypes, _
        ByVal pr_Method As RegistrationListenerMethods)

Dim vl_MethodName As String
Dim vl_Name As String
Dim vl_TypeString As String

Select Case pr_InterfaceType
Case rltClass
    vl_TypeString = "Class"
Case rltMethod
    vl_TypeString = "Method"
End Select

Select Case pr_Method
Case rlmAfterAddded
    vl_MethodName = "after" & vl_TypeString & "Added"
Case rlmAfterRemoved
    vl_MethodName = "after" & vl_TypeString & "Removed"
Case rlmBeforeAdded
    vl_MethodName = "before" & vl_TypeString & "AddedCancelOpprotunity"
Case rlmBeforeRemoved
    vl_MethodName = "before" & vl_TypeString & "RemovedCancelOpprotunity"
End Select

getRegInterfaceMethodName = vl_MethodName
End Function

Public Function callListeners( _
        ByVal pr_Iterators As Object, _
        ByVal pr_Method As String, _
        ParamArray argList()) As Boolean 'ByVal pr_Iterators As LLIterator, _
        ByVal pr_Method As String, _
        ByRef pr_LastReferenceBool As Boolean, _
        ParamArray argList()) As Boolean

Dim vl_Arrays() As Variant
Dim vl_NewUBound As Integer

'We set arglist to arglist(0) because of the methods that call this method. There's a bit of a "chain calling" that's done
'between the core and this method that creates arrays inside of arrays. The previously calling method must pass item(), and
'all subsequent methods utilizing paramarray must pass (). There must be an even number of calls in order for the next
'code snippet to succeed.
vl_Arrays = argList(0)


Select Case UBound(vl_Arrays)
Case 0
    CallByName pr_Iterators, pr_Method, VbMethod, vl_Arrays(0)
Case 1
    CallByName pr_Iterators, pr_Method, VbMethod, vl_Arrays(0), vl_Arrays(1)
Case 2
    CallByName pr_Iterators, pr_Method, VbMethod, vl_Arrays(0), vl_Arrays(1), vl_Arrays(2)
Case 3
    CallByName pr_Iterators, pr_Method, VbMethod, vl_Arrays(0), vl_Arrays(1), vl_Arrays(2), vl_Arrays(3)
Case 4
    CallByName pr_Iterators, pr_Method, VbMethod, vl_Arrays(0), vl_Arrays(1), vl_Arrays(2), vl_Arrays(3), vl_Arrays(4)
End Select
    
End Function
